/*
 * listenhandler.h
 *
 *  Created on: 2013. 7. 19.
 *      Author: jjaehuny
 */

#ifndef LISTENHANDLER_H_
#define LISTENHANDLER_H_

#include <Dispatcher/Static.h>
#include "ChannelServer.h"

#include <time.h>

#include "Static.h"
#include "User.h"

namespace CacheServer
{

class ListenHandler : public Dispatcher::ListenHandler<ChannelServer, Network::Packet>
{
public:

	ListenHandler() {}
	virtual ~ListenHandler() {}

	virtual void OnConnect(ChannelServer* pSession, const char* ip)
	{
		LOG(DEV, "(session_key:", pSession->GetSessionKey(), ", sock:", pSession->GetSocket(), ", ip:", ip, ")");
	}
	virtual void OnClose(ChannelServer* pSession, int nReason)
	{
		LOG(DEV, "(session_key:", pSession->GetSessionKey(), ", sock:", pSession->GetSocket(), ", errno:", nReason, " errstr:", strerror(errno), ")");
		LOG(DEV, "(channel_key:", pSession->GetChannelKey(), ", sock:", pSession->GetSocket(), ", errno:", nReason, " errstr:", strerror(errno), ")");

		std::for_each(Static::Instance().s_clsTreeVector.begin(), Static::Instance().s_clsTreeVector.end(), [&](MAP & map) {

			std::for_each(map.begin(), map.end(), [&](MAP::value_type & pair) {
				if ( pSession->GetChannelKey() == pair.second->GetChannelKey())
				{
					//pair.second->SetRandomTime();
				}
			} );

		} );
	}
	virtual void OnRecvMsg(Session* pSession, Packet* pPacket)
	{
		typename Session::State* pState = pSession->GetState();
		if (NULL == pState)
		{
			LOG(ERR, "session has no state(session_key:", pSession->sessionKey_, ")");
			return ;
		}

		typename Session::State::Command pCommand = pState->GetCommand(pPacket->GetCommand());
		if (NULL == pCommand)
		{
			LOG(ERR, "state has no command(session_key:", pSession->sessionKey_, ", command_id:", pPacket->GetCommand(), ")");
			return ;
		}
		unsigned long start = GetTime();
		(*pCommand)(pSession, pPacket);
		unsigned long end = GetTime();
		LOG(INF, "[ PROCESS COMMAND : ", pPacket->GetCommand(), " START : ", start, " END : ", end, " GAB : ", end - start, " ]");
	}
	// return milli second
	unsigned int GetTime()
	{
		struct timespec ts;
		::clock_gettime(CLOCK_MONOTONIC, &ts);
		return ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
	}
};

} /* namespace cacheserver */


#endif /* LISTENHANDLER_H_ */
